package com.hejjon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hejjon.core.domain.entity.FeatureCategory;
import com.hejjon.core.domain.vo.FeatureCategoryVO;
import com.hejjon.core.enumer.DeleteFlagEnum;
import com.hejjon.core.enumer.FeatureKindEnum;
import com.hejjon.core.enumer.ViewState;
import com.hejjon.core.exception.BusinessException;
import com.hejjon.core.utils.StrUtil;
import com.hejjon.core.utils.TreeBuilder;
import com.hejjon.mapper.FeatureCategoryMapper;
import com.hejjon.service.IBasicTypeService;
import com.hejjon.service.IBusinessAttrService;
import com.hejjon.service.IFeatureCategoryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 特征分类业务
 * @author: cs
 * @date: 2025-02-26 16:27:08
 * @since: 1.0
 */
@Service
public class FeatureCategoryServiceImpl extends ServiceImpl<FeatureCategoryMapper, FeatureCategory>
        implements IFeatureCategoryService {

    @Resource
    private IBusinessAttrService businessAttrService;

    @Resource
    private IBasicTypeService basicTypeService;


    @Override
    public boolean createCategory(FeatureCategory entity) {
        String name = entity.getName();
        String kind = entity.getKind();
        if (StringUtils.isEmpty(name)) {
            throw new BusinessException("特征分类名称不可为空");
        }
        if (StringUtils.isEmpty(kind)) {
            throw new BusinessException("特征分类种类不可为空");
        }
        Integer exit = baseMapper.exitByNameAndKind(kind, name);
        if (exit != null) {
            throw new BusinessException("特征分类名称已存在");
        }
        entity.setId(StrUtil.getUUID());
        entity.setHide(ViewState.SHOW.getTag());
        entity.setIcon("");
        entity.setCreateBy("admin");
        entity.setDeleteFlag(DeleteFlagEnum.NO.getCode());
        entity.setCreateTime(LocalDateTime.now());
        return super.save(entity);
    }


    /**
     * 根据
     * @param kind
     * @return
     */
    @Override
    public List<FeatureCategoryVO> findTreeData(String kind) {
        LambdaQueryWrapper<FeatureCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FeatureCategory::getDeleteFlag, DeleteFlagEnum.NO.getCode());
        wrapper.eq(FeatureCategory::getKind, kind).orderBy(true, true, FeatureCategory::getCreateTime);
        List<FeatureCategory> list = list(wrapper);
        return buildTreeData(list);

    }


    @Override
    public boolean removeById(String id, String kind) {
        // 检查是否有子节点
        LambdaQueryWrapper<FeatureCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FeatureCategory::getParentId, id);
        wrapper.eq(FeatureCategory::getDeleteFlag, DeleteFlagEnum.NO.getCode());
        boolean exists = exists(wrapper);
        if (exists) {
            throw new BusinessException("当前节点包含子节点, 请先删除子节点");
        }
        // 检查该分类下是否包含业务数据 包括基础类型、业务属性、业务对象等
        FeatureKindEnum kindEnum = FeatureKindEnum.valueOf(kind);
        switch (kindEnum) {
            case basicType:
                boolean exit1 = basicTypeService.existByCategoryId(id);
                if (exit1) {
                    throw new BusinessException("该类目包含基础类型数据，不可删除！");
                }
                break;
            case busiAttr:
                boolean exit = businessAttrService.exitByCategoryId(id);
                if (exit) {
                    throw new BusinessException("该类目包含业务属性数据，不可删除！");
                }
                break;
            case business:
                // System.out.println("");
                break;
            default:
                break;
        }

        return baseMapper.update(new LambdaUpdateWrapper<FeatureCategory>()
                .eq(FeatureCategory::getId,id)
                .eq(FeatureCategory::getDeleteFlag,DeleteFlagEnum.NO.getCode())
                .set(FeatureCategory::getDeleteFlag,DeleteFlagEnum.YES.getCode())
                .set(FeatureCategory::getUpdateBy,"admin").set(FeatureCategory::getUpdateTime,LocalDateTime.now())) > 0;

    }


    @Override
    public boolean updateCategory(FeatureCategory category) {

        String id = category.getId();
        String kind = category.getKind();
        FeatureCategory dbEntity = baseMapper.selectById(id);
        if (dbEntity == null) {
            throw new BusinessException("特征分类不存在! 名称: " + category.getName());
        }

        String name = category.getName();
        String dbName = dbEntity.getName();
        if (!StringUtils.equals(name, dbName)) {
            // 更新了name属性
            LambdaQueryWrapper<FeatureCategory> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(FeatureCategory::getKind, kind);
            wrapper.eq(FeatureCategory::getName, name);
            wrapper.eq(FeatureCategory::getDeleteFlag,DeleteFlagEnum.NO.getCode());
            boolean exists = exists(wrapper);
            if (exists) {
                throw new BusinessException("特征分类名称已存在, 不可重复!");
            }
        }
        // alias 保存上一次的旧名字
        category.setAlias(dbName);
        category.setUpdateBy("admin");
        category.setUpdateTime(LocalDateTime.now());

        return updateById(category);
    }


    @Override
    public List<FeatureCategory> findByKind(String kind) {
        LambdaQueryWrapper<FeatureCategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FeatureCategory::getKind, kind);
        wrapper.eq(FeatureCategory::getDeleteFlag,DeleteFlagEnum.NO.getCode());
        return list(wrapper);
    }


    @Override
    public List<FeatureCategoryVO> buildTreeData(List<FeatureCategory> list) {
        List<FeatureCategoryVO> voList = new ArrayList<>();

        Map<String, String> idtextMap = new HashMap<>();
        list.forEach(category -> idtextMap.put(category.getId(), category.getName()));
        list.forEach(category -> {
            FeatureCategoryVO vo = new FeatureCategoryVO();
            vo.setId(category.getId());
            vo.setParentId(category.getParentId());
            vo.setName(category.getName());
            vo.setLabel(category.getName());            // element ui
            vo.setAlias(category.getAlias());
            vo.setKind(category.getKind());
            vo.setHide(category.getHide());
            vo.setLastModifyTime(category.getUpdateTime() == null ? category.getCreateTime() : category.getUpdateTime());
            vo.setLastModifyUser(category.getUpdateBy() == null ? category.getCreateBy() : category.getUpdateBy());
            if (idtextMap.containsKey(category.getParentId())) {
                vo.setParentLabel(idtextMap.get(category.getParentId()));
            }
            voList.add(vo);
        });
        TreeBuilder<FeatureCategoryVO, String> treeBuilder = new TreeBuilder<>();
        return treeBuilder.buildTree(voList);
    }


}
